/**   
* @Title: WorkDataManager.java 
* @Package net.gdface.worker 
* @Description: TODO 
* @author guyadong   
* @date 2015年5月14日 下午8:52:54 
* @version V1.0   
*/
package net.gdface.worker;

import java.net.URI;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.gdface.utils.Assert;
import net.gdface.utils.Judge;

/**
 * 管理工作线程正在使用的工作对象数据{@link WorkData}<br>
 * 一项任务开始执行时，对应的{@link WorkData}被加入{@link WorkDataManager}<br>
 * 任务结束，则从{@link WorkDataManager}中移除<br>
 * 使用{@link ConcurrentMap}保存工作数据对象,以保证不可能有相同{@link URI}的两个任务同时执行<br>
 * @author guyadong
 *
 */
public class WorkDataManager {
	protected static final Logger logger = LoggerFactory.getLogger(WorkDataManager.class);

	/**
	 * 当前正在执行的工作对象
	 */
	private final ConcurrentMap<URI, WorkData> working = new ConcurrentHashMap<URI, WorkData>(
			65536, 0.75f, 1024);

	public WorkDataManager() {
	}

	/**
	 * @param key
	 * @param value
	 * @return previous {@link WorkData}
	 * @see java.util.concurrent.ConcurrentMap#putIfAbsent(java.lang.Object, java.lang.Object)
	 */
	public WorkData putIfAbsent(URI key, WorkData value) {
		return working.putIfAbsent(key, value);
	}
	/**
	 * @param value
	 * @return previous {@link WorkData}
	 * @see java.util.concurrent.ConcurrentMap#putIfAbsent(java.lang.Object, java.lang.Object)
	 */
	public WorkData putIfAbsent(WorkDataWithURI value) {
		URI key = value.getURI();
		Assert.notNull(key, "key");
		return working.putIfAbsent(key, value);
	}
	/**
	 * 将{@code uri}映射的工作对象{@code woc}从当前工作对象表中移除
	 * @param uri
	 * @param woc
	 * @return true if the value was removed
	 * @see java.util.concurrent.ConcurrentMap#remove(java.lang.Object, java.lang.Object)
	 */
	public boolean remove(URI uri, WorkData woc) {
		if (Judge.hasNull(uri, woc))
			return false;
		boolean removed = working.remove(uri, woc);
		if(!removed){
			logger.error(String.format("无法从工作管理器中删除指定对象[%s]",uri));
		}

		return removed;
	}
	
	/**
	 * 将工作对象{@code woc}从当前工作对象表{@link #working}中移除<br>
	 * key将从{@link WorkDataWithURI}容器对象中的已知数据对象中获取，如果获取不到则抛出异常
	 * @param woc
	 * @return true if the value was removed
	 * @throws RuntimeException 没有办法找到key,可从{@link RuntimeException#getCause()}得到具体原因
	 * @see #remove(URI, WorkData)
	 */
	public boolean remove(WorkDataWithURI woc) throws RuntimeException {
		if (null == woc)
			return false;
		return remove(woc.getURI(), woc);
	}
	/**
	 * @param uri
	 * @return the {@link WorkData} to which the specified key is mapped, or null if this map contains no mapping for the key
	 * @see java.util.Map#get(java.lang.Object)
	 */
	public WorkData get(URI uri) {
		return working.get(uri);
	}

	/**
	 * @return the number of {@link WorkData} in this map
	 * @see java.util.Map#size()
	 */
	public int size() {
		return working.size();
	}

/*	public <T> T setVariable(URI uri, String name, T value) {
		if (null==uri || Judge.isEmpty(name))
			return null;
		WorkData woc = working.get(uri);
		Assert.notNull(woc, "woc");
		return woc.setVariables(name, value);
	}

	public <T> T getVariable(URI uri, String name) {
		if (null == uri || Judge.isEmpty(name))
			return null;
		WorkData woc = working.get(uri);
		if (null == woc)
			return null;
		return woc.getVariables(name);
	}*/

}
